package com.gsdl.web.controller;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;

import org.apache.log4j.Logger;

import com.gsdl.model.delegate.BusinessDelegate;
import com.gsdl.model.entity.Deposito;
import com.gsdl.model.entity.Material;
import com.gsdl.model.entity.Movimento;
import com.gsdl.model.entity.Pedido;
import com.gsdl.model.entity.Pedido.EstadoPedido;
import com.gsdl.model.entity.Stock;
import com.gsdl.model.entity.TipoPedido;
import com.gsdl.web.util.JsfUtil;


// TODO: Auto-generated Javadoc
/**
 * The Class PedidoController.
 *
 * @author Natacha Antonopoulos
 */

@ManagedBean
@ViewScoped
public class PedidoController implements Serializable{
	
	/** The Constant serialVersionUID. */
	private static final long serialVersionUID = 1L;
	
	/** The Constant LOG. */
	private static final Logger LOG = Logger.getLogger(PedidoController.class.getName());
	
	
	/** The pedido. */
	private Pedido pedido = new Pedido();
	
	/** The novo pedido. */
	private Pedido novoPedido = new Pedido();
		
	/** The pedidos. */
	private List<Pedido> pedidos = new ArrayList<Pedido>();
	
	/** The tipos pedido. */
	private List<TipoPedido> tiposPedido = new ArrayList<TipoPedido>();

	/** The anular. */
	private boolean anular = false;
	
	/** The centro stock list. */
	private List<Stock> centroStockList = new ArrayList<Stock>();
	
	/** The movimento. */
	private Movimento movimento = new Movimento();
	
	/** The stock. */
	private Stock stock = new Stock();
	
	/** The movimentos. */
	private List<Movimento> movimentos = new ArrayList<Movimento>();
	
	/** The login controller. */
	@ManagedProperty(value="#{loginController}")
   	private LoginController loginController;
	
	/**
	 * Check if there is a pedidoId as a request parameter. If there is sets the pedido for details view
	 */
	@PostConstruct
	private void init() {
		String pedidoId = JsfUtil.getRequestParameter("pedidoId");
		if(pedidoId != null && !pedidoId.equals("")){
			pedido = BusinessDelegate.getInstance().getPedidoById(Long.parseLong(pedidoId));
			anular = false;
			movimentos = new ArrayList<Movimento>();
			movimentos = pedido.getMovimentos();
		}
	}
	
	/**
	 * Save pedido action.
	 *
	 * @return the string
	 */
	public String savePedidoAction(){
		try {
			
			if(anular){
				pedido.setEstadoPedido(EstadoPedido.ANULADO);
				pedido = BusinessDelegate.getInstance().savePedidoAnulacao(pedido, movimentos);
			}else
				pedido = BusinessDelegate.getInstance().savePedido(pedido, movimentos);
			
			JsfUtil.addSuccessMessage("Pedido actualizado com sucesso");
			return "pedidos";
			
		}catch (Exception ex) {
			ex.printStackTrace();
			JsfUtil.addErrorMessage(ex.getMessage());
        }
		return "";
	}
	
	/**
	 * Save new pedido action.
	 *
	 * @return the string
	 */
	public String saveNewPedidoAction(){
		try {
			novoPedido.setUtilizador(loginController.getUtilizador());
			novoPedido = BusinessDelegate.getInstance().savePedido(novoPedido, movimentos);
			JsfUtil.addSuccessMessage("Pedido registado com sucesso");
			return "pedidos";
		}catch (Exception ex) {
			JsfUtil.addErrorMessage("Erro ao registar pedido");
        }
		return "";
	}
	
	
	/**
	 * Novo movimento.
	 *
	 * @return the string
	 */
	public String novoMovimento(){
		
		List<Stock> list = BusinessDelegate.getInstance().getStockByDepositoAndMaterial(stock.getDeposito(), stock.getMaterial());
		stock = list.get(0);
		Long quantidadeStock = stock.getQuantidade();
		Long quantidadeMovimento = movimento.getQuantidade();
		
		if(quantidadeStock < quantidadeMovimento){
			JsfUtil.addErrorMessage(JsfUtil.getResourceMessage("erroQuantidadeStock"));
//			JsfUtil.getResourceMessage("erroQuantidadeStock");
			return "";
		}
		
		Long limite = quantidadeStock - quantidadeMovimento;
		
		if(stock.getMaterial().getLimite() > limite){
			JsfUtil.addWarningMessage(JsfUtil.getResourceMessage("avisoLimiteStock"));
		}
		
		movimento.setDeposito(stock.getDeposito());
		movimento.setMaterial(stock.getMaterial());
		
		movimentos.add(movimento);
		movimento = new Movimento();
		stock = new Stock();
		stock.setDeposito(new Deposito());
		stock.setMaterial(new Material());
		return "";
	}
	
	
	
	/**
	 * Novo pedido.
	 *
	 * @return the string
	 */
	public String novoPedido(){
		novoPedido = new Pedido();
//		novoPedido.setTipoPedido(new TipoPedido());
		movimento = new Movimento();
		stock = new Stock();
		stock.setDeposito(new Deposito());
		stock.setMaterial(new Material());
		movimentos = new ArrayList<Movimento>();
		return "novoPedido";
	}
	
	
	/**
	 * Removes the material.
	 *
	 * @param index the index
	 * @return the string
	 */
	public String removeMaterial(int index){
		movimentos.remove(index);
		return "";
	}
	
	/**
	 * Save expedicao.
	 *
	 * @return the string
	 */
	public String saveExpedicao(){
		BusinessDelegate.getInstance().saveExpedicao(pedido);
		return "pedidos";
	}

	/**
	 * Gets the pedido.
	 *
	 * @return the pedido
	 */
	public Pedido getPedido() {
		return pedido;
	}

	/**
	 * Sets the pedido.
	 *
	 * @param pedido the new pedido
	 */
	public void setPedido(Pedido pedido) {
		this.pedido = pedido;
	}

	/**
	 * Gets the pedidos.
	 *
	 * @return the pedidos
	 */
	public List<Pedido> getPedidos() {
		pedidos = BusinessDelegate.getInstance().getAllPedidos();
		return pedidos;
	}

	/**
	 * Sets the pedidos.
	 *
	 * @param pedidos the new pedidos
	 */
	public void setPedidos(List<Pedido> pedidos) {
		this.pedidos = pedidos;
	}

	/**
	 * Gets the novo pedido.
	 *
	 * @return the novoPedido
	 */
	public Pedido getNovoPedido() {
		return novoPedido;
	}

	/**
	 * Sets the novo pedido.
	 *
	 * @param novoPedido the novoPedido to set
	 */
	public void setNovoPedido(Pedido novoPedido) {
		this.novoPedido = novoPedido;
	}

	/**
	 * Gets the tipos pedido.
	 *
	 * @return the tiposPedido
	 */
	public List<TipoPedido> getTiposPedido() {
		if(tiposPedido == null || tiposPedido.isEmpty())
			tiposPedido = BusinessDelegate.getInstance().getTiposPedido();
		return tiposPedido;
	}

	/**
	 * Sets the tipos pedido.
	 *
	 * @param tiposPedido the tiposPedido to set
	 */
	public void setTiposPedido(List<TipoPedido> tiposPedido) {
		this.tiposPedido = tiposPedido;
	}


	/**
	 * Gets the login controller.
	 *
	 * @return the loginController
	 */
	public LoginController getLoginController() {
		return loginController;
	}

	/**
	 * Sets the login controller.
	 *
	 * @param loginController the loginController to set
	 */
	public void setLoginController(LoginController loginController) {
		this.loginController = loginController;
	}

	
	/**
	 * Gets the stock.
	 *
	 * @return the stock
	 */
	public Stock getStock() {
		return stock;
	}

	/**
	 * Sets the stock.
	 *
	 * @param stock the stock to set
	 */
	public void setStock(Stock stock) {
		this.stock = stock;
	}

	/**
	 * Gets the movimento.
	 *
	 * @return the movimento
	 */
	public Movimento getMovimento() {
		return movimento;
	}

	/**
	 * Sets the movimento.
	 *
	 * @param movimento the movimento to set
	 */
	public void setMovimento(Movimento movimento) {
		this.movimento = movimento;
	}

	/**
	 * Gets the movimentos.
	 *
	 * @return the movimentos
	 */
	public List<Movimento> getMovimentos() {
		return movimentos;
	}

	/**
	 * Sets the movimentos.
	 *
	 * @param movimentos the movimentos to set
	 */
	public void setMovimentos(List<Movimento> movimentos) {
		this.movimentos = movimentos;
	}

	/**
	 * Checks if is anular.
	 *
	 * @return the anular
	 */
	public boolean isAnular() {
		return anular;
	}

	/**
	 * Sets the anular.
	 *
	 * @param anular the anular to set
	 */
	public void setAnular(boolean anular) {
		this.anular = anular;
	}

	/**
	 * Gets the depositos expedicao.
	 *
	 * @return the depositosExpedicao
	 */
	public List<Deposito> getDepositosExpedicao() {
		List<Deposito> depositosExpedicao = new ArrayList<Deposito>();
		if(novoPedido.getCentro().getId() != null)
			depositosExpedicao = BusinessDelegate.getInstance().getDepositoExpedicaoByCentro(novoPedido.getCentro());
		return depositosExpedicao;
	}

	
	/**
	 * Gets the depositos.
	 *
	 * @return the depositos de Armazenamento
	 */
	public List<Deposito> getDepositos() {
		List<Deposito> depositos = new ArrayList<Deposito>();
		if(novoPedido.getCentro().getId() != null)
			depositos = BusinessDelegate.getInstance().getDepositoArmazenamentoByCentro(novoPedido.getCentro());
		
		
		return depositos;
	}
	
	/**
	 * Gets the materiais.
	 *
	 * @return the depositosExpedicao
	 */
	public List<Material> getMateriais() {
		List<Material> materiais = new ArrayList<Material>();
		if(novoPedido.getCentro().getId() != null)
			materiais = BusinessDelegate.getInstance().getMaterialByCentro(novoPedido.getCentro());
		return materiais;
	}

	/**
	 * Gets the centro stock list.
	 *
	 * @return the centroStockList
	 */
	public List<Stock> getCentroStockList() {
		if(novoPedido.getCentro().getId() != null &&  stock.getMaterial() != null)
			centroStockList = BusinessDelegate.getInstance().getByCentroAndMaterial(novoPedido.getCentro(), stock.getMaterial());
		return centroStockList;
	}

	/**
	 * Sets the centro stock list.
	 *
	 * @param centroStockList the centroStockList to set
	 */
	public void setCentroStockList(List<Stock> centroStockList) {
		this.centroStockList = centroStockList;
	}
}
